iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Software Development

從 Vibe Coding 到可維護專案:用 Hermes Agent 重讀 RoomRush Android 專題系列 第 17 篇

Day 17 | 我發現一個危險問題:管理者修改可能被 CSV 蓋掉

  • 分享至 

  • xImage
  •  

前言:為什麼管理者修改可能被 CSV 重新匯入覆蓋?

前幾天我一路追著 RoomRush 的資料來源,把原本分散在不同檔案裡的流程串了起來:

SF.csv / ES.csv
    ↓
AppDatabase.parseCsv()
    ↓
ClassroomSchedule
    ↓
Room Database
    ↓
DAO
    ↓
Repository
    ↓
AppContainer
    ↓
ViewModel
    ↓
空教室查詢結果

這條流程讓我理解課表資料從哪裡來、怎麼存進資料庫,以及最後怎麼被查詢使用。

但當我開始準備往管理者功能看時,出現了一個新的問題:如果管理者要修改這些資料,修改後的資料會一直保留下來嗎? 這個問題讓我重新回頭看了資料庫初始化的流程。
這不是單純的猜測,而是從實際程式碼確認出的資料生命週期問題。


一開始我認為

一開始看到 SF.csv、ES.csv 時,我很自然地把它們理解成:「App 第一次建立資料庫時,用來提供初始課表的資料。」

所以我的想法很簡單:

CSV
    ↓
建立初始資料
    ↓
Room Database
    ↓
之後 App 都從 Room 讀取

所以如果管理者修改了一間教室的資料,我直覺會認為:「那就把 Room 裡的資料改掉就好了。」

但問題是:CSV 還在那裡,如果 CSV 裡面的資料沒有跟著改,那它和資料庫裡的資料就可能開始不一樣。


實際讀完程式碼後

回到程式碼:

override fun onCreate(db: SupportSQLiteDatabase) {
    super.onCreate(db)
    triggerPopulate()
}

override fun onOpen(db: SupportSQLiteDatabase) {
    super.onOpen(db)
    triggerPopulate()
}

流程:

onOpen()
    ↓
triggerPopulate()
    ↓
讀取 CSV
    ↓
parseCsv()
    ↓
dao.insertAll()
    ↓
REPLACE

我在 AppDatabase 裡看到,資料庫建立時的 onCreate() 和每次開啟資料庫時的 onOpen(),都會觸發預載資料的流程。

繼續追下去後,我發現 triggerPopulate() 會重新讀取 CSV,解析成 ClassroomSchedule,最後透過 DAO 寫回資料庫,而且這裡使用的是 REPLACE。

這才讓原本的問題變得明確:如果管理者修改過的資料和 CSV 不一樣,下一次重新匯入時,CSV 的資料就可能取代管理者修改後的資料。


把兩條資料寫入路徑放在一起

先不管實際是哪一行程式碼,單純從「資料從哪裡來」來看:

CSV 資料預載

SF.csv / ES.csv
    ↓
parseCsv()
    ↓
ClassroomSchedule
    ↓
DAO
    ↓
Room Database

管理者修改

管理者
    ↓
ViewModel
    ↓
Repository
    ↓
DAO
    ↓
Room Database

這時候真正的問題就出現了:

SF.csv / ES.csv
       ↓
  Room Database
       ↑
       │
    管理者

「同一個資料庫,開始有兩個方向的資料來源。」


舉一個最直觀的例子

假設 CSV 一開始記錄:SF130 是普通教室。後來管理者進入後台,把 SF130 改成實驗室。

如果修改成功,現在資料庫裡是:

SF130 → 實驗室

但 CSV 裡還是:

SF130 → 一般教室

那如果某個時候 App 又重新載入 CSV:

SF130 到底應該是一般教室,還是實驗室?

這就是我覺得值得注意的地方。

因為這已經不是單純的「資料有沒有存成功」,而是:這個專案到底把誰當成資料的最終來源?


Hermes Agent 幫我檢查出的重點

這次我沒有直接問 Hermes:「這段程式碼有什麼問題?」

而是讓它幫我把幾個分散的流程放在一起比較:

  • CSV 載入流程
  • Room Database
  • 管理者修改流程
  • DAO / Repository

再回到實際程式碼逐一確認。

這次 AI 對我最大的幫助不是「告訴我答案」,而是幫我把原本分開看的兩條流程放到同一張圖裡。


小結

今天我原本只是想繼續往下了解管理者功能,卻意外發現了資料生命週期上的問題。

前面我一直在追問:「資料怎麼流動?」;但今天開始,我第一次問:「資料到底是誰說了算?」

CSV 是課表的原始資料,而管理者又可以修改 Room Database 裡的資料。當我把這兩條寫入路徑放在一起後,才發現:資料能被寫進資料庫,不代表資料的生命週期就被設計好了。

更具體來說,目前 onOpen() 會重新觸發 CSV 匯入,而匯入使用 REPLACE,因此管理者修改過的資料可能在重新匯入後被原始 CSV 取代。

這不是單純某個畫面顯示錯誤,而是資料初始化與管理者修改之間,缺少明確資料生命週期策略的問題。


下一篇預告:管理者登入看起來能用,但安全性真的夠嗎?

既然管理者可以修改 App 裡的重要資料,接下來就正式進入到第三階段-「管理者功能主線」,管理者到底可以修改哪些資料?誰有權限進行這些修改?

管理者功能的第一個入口就是登入功能- LoginActivity.kt,下一篇會介紹到:關於「管理者功能」到底是怎麼進來的?


上一篇
Day 16 | 從 CSV 到畫面:RoomRush 的資料流我終於串起來了
下一篇
Day 18 | 管理者登入看起來能用,但安全性真的夠嗎?
系列文
從 Vibe Coding 到可維護專案:用 Hermes Agent 重讀 RoomRush Android 專題 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言